package com.naver.java3d;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.net.MalformedURLException;
import java.net.URL;

import javax.media.j3d.Alpha;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Texture;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Point3d;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class CubeViewer extends Applet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private URL[] urls;
	private SimpleUniverse universe = null;
	private BranchGroup branchGroup = null;
	private TransformGroup transformGroup = null;
	private BoundingSphere boundingSphere = null; 

	public CubeViewer(URL[] urls) {
		this.urls = urls;
	}
	
	public static void main(String[] args) throws MalformedURLException {
		String path = "/Users/monster/Documents/workspace/tech-prj/src/main/resources/images/";
		URL[] urls = {
			new URL("file:" + path + "front_512.jpg"),
			new URL("file:" + path + "left_512.jpg"),
			new URL("file:" + path + "back_512.jpg"),
			new URL("file:" + path + "right_512.jpg"),
			new URL("file:" + path + "top_512.jpg"),
			new URL("file:" + path + "bottom_512.jpg")};
		
		new MainFrame(new CubeViewer(urls), 512, 512);
	}

	@Override
	public void init() {
		setLayout(new BorderLayout());
		GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
		Canvas3D c = new Canvas3D(config);
		add("Center", c);
		createUniverse(c);
		createSceneGraph();
		createBehaviourInteractors();
		universe.getViewingPlatform().setNominalViewingTransform();
		universe.addBranchGraph(branchGroup);
	}
	
	private void createUniverse(Canvas3D canvas3D) {
		universe = new SimpleUniverse(canvas3D);
		branchGroup = new BranchGroup();
		transformGroup = new TransformGroup();
		boundingSphere = new BoundingSphere();
	}

	private void createSceneGraph() {
		transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		branchGroup.addChild(transformGroup);

		Box cube = new Box(0.6f, 0.6f, 0.6f, Box.GENERATE_TEXTURE_COORDS, null);

		setEachTexture(urls[0], Box.FRONT, cube);
		setEachTexture(urls[1], Box.LEFT, cube);
		setEachTexture(urls[2], Box.BACK, cube);
		setEachTexture(urls[3], Box.RIGHT, cube);
		setEachTexture(urls[4], Box.TOP, cube);
		setEachTexture(urls[5], Box.BOTTOM, cube);

		transformGroup.addChild(cube);
		Transform3D yAxis = new Transform3D();
		Transform3D xAxis = new Transform3D();
		xAxis.rotZ(Math.PI/2.0f);
		Alpha alpha1 = new Alpha(-1, 8000);
		Alpha alpha2 = new Alpha(-1, 8000);
//		RotationInterpolator rotatorY = new RotationInterpolator(alpha1, transformGroup, yAxis, 0.0f, (float)Math.PI * 2.0f);
		RotationInterpolator rotatorX = new RotationInterpolator(alpha2, transformGroup, xAxis, 0.0f, (float)Math.PI * 2.0f);
//		rotatorY.setSchedulingBounds(bounds);
//		rotatorX.setSchedulingBounds(boundingSphere);
//		transformGroup.addChild(rotatorY);
		transformGroup.addChild(rotatorX);
//		branchGroup.compile();
	}

	public void setEachTexture(URL url, int face, Box cube) {
		Appearance appearance = new Appearance();
		Texture texture = new TextureLoader(url, this).getTexture();
		appearance.setTexture(texture);
		TextureAttributes attributes = new TextureAttributes();
		attributes.setTextureMode(TextureAttributes.MODULATE);
		appearance.setTextureAttributes(attributes);
		cube.setAppearance(face, appearance);
	}
	
	private void createBehaviourInteractors() {
		TransformGroup viewTransformGroup = universe.getViewingPlatform().getViewPlatformTransform();
		KeyNavigatorBehavior keyInteractor = new KeyNavigatorBehavior(viewTransformGroup);
		BoundingSphere movingBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
		keyInteractor.setSchedulingBounds(movingBounds);
		branchGroup.addChild(keyInteractor);
		MouseRotate behavior = new MouseRotate();
		behavior.setTransformGroup(transformGroup);
		branchGroup.addChild(behavior);
		behavior.setSchedulingBounds(boundingSphere);
	}
	

	@Override
	public void destroy() {
		universe.cleanup();
	}
}
